home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Supervisor's Toolkit
/
Network Supervisor's Toolkit.iso
/
tools
/
nwtp06
/
nwsema.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1996-07-10
|
10KB
|
330 lines
{$X+,B-,V-} {essential compiler directives}
Unit nwSema;
{ nwSema unit as of 950301 / NwTP 0.6 API. (c) 1993,1995, R.Spronk }
INTERFACE
{ Primary functions: Interrupt: comments:
* CloseSemaphore (F220/04)
* ExamineSemaphore (F220/01)
* GetConnectionsSemaphores (F217/F1)
* GetSemaphoreInformation (F217/F2)
* OpenSemaphore (F220/00)
* SignalSemaphore (F220/03)
* WaitOnSemaphore (F220/02)
Notes: Functions marked with a '*' have been tested and found correct.
}
Uses nwIntr,nwMisc;
Type TsemaInfo=record
ConnNbr:word;
TaskNbr:word;
end;
TsemaInfoList=array[1..100] of TsemaInfo;
{ used by GetSemaphoreInformation }
TconnSema=record
OpenCount: Byte;
Value : Integer;
TaskNbr : Word;
unknown : byte; { always 00 ?! }
Name : string[127];
end;
{ used by GetConnectionsSemaphores }
Var Result:word;
{F220/00 [2.15? 3.x]}
Function OpenSemaphore(SemName : String; InitVal : Integer;
VAR SemHandle : LongInt;
VAR OpenCount : Word ):Boolean;
{F220/01 [2.15? 3.x]}
FUNCTION ExamineSemaphore( SemHandle :LongInt;
VAR Value :Integer;
VAR OpenCount :Word ) :Boolean;
{ This functions returns the current value and open count of a semaphore.}
{F220/02 [3.x]}
FUNCTION WaitOnSemaphore( SemHandle :LongInt;
Wait_Time :Word ) :Boolean;
{ Decrement the semaphore value and, if it is negative, }
{ wait until it becomes non-negative or until a timeout occurs. }
{F220/03 [3.x]}
FUNCTION SignalSemaphore(SemHandle:LongInt) : Boolean;
{ Increment the semaphore value and release if waiting. }
{F220/04 [3.x]}
FUNCTION CloseSemaphore(SemHandle:LongInt) : Boolean;
{ Decrement the open count of a semaphore.}
{ When the open count goes to zero, the semaphore is destroyed. }
{F217/F1 [2.15+? 3.x+]}
Function GetConnectionsSemaphores(ConnNbr:Word;
{i/o} Var seqNbr:Word;
{out} Var NbrOfSemaLeft:Byte;
{out} Var SemaInfo:TconnSema):Boolean;
{Caller needs console privileges }
{F217/F2 [2.15? 3.x+]}
Function GetSemaphoreInformation(SemaName:String;
{i/o} Var seqNbr:word;
{out} Var OpenCount:word;
Var SemValue:Integer;
Var NbrOfSemaLeft:byte;
Var info:TsemaInfoList):Boolean;
{ Caller needs console privileges }
IMPLEMENTATION {=============================================================}
{F220/00 [3.x]}
Function OpenSemaphore(SemName : String; InitVal : Integer;
VAR SemHandle : LongInt;
VAR OpenCount : Word ):Boolean;
Type Treq=Record
subf:byte;
_InitVal:byte;
_SemNameLen:byte;
_SemName:array[0..127] of byte;
end;
Trep=record
_SemHandle:LongInt;
_OpenCount:Byte;
end;
TPreq=^Treq;
TPrep=^Trep;
begin
With TPreq(GlobalReqBuf)^
do begin
subf:=$00;
If InitVal<0
then _InitVal:=Lo(256+Initval)
else _InitVal:=Lo(InitVal);
UpString(SemName);SemName:=SemName+#0;
move(semName[1],_SemName[0],ord(SemName[0]));
_SemNameLen:=ord(semName[0])-1;
end;
F2SystemCall($20,SizeOf(treq),SizeOf(trep),result);
With TPrep(GlobalReplyBuf)^
do begin
SemHandle:=Lswap(_SemHandle);
OpenCount:=_OPenCount;
end;
OpenSemaphore:=(result=0);
end;
{F220/02 [3.x]}
Function WaitOnSemaphore( SemHandle : LongInt;
Wait_Time : Word ) : Boolean;
{ Decrement the semaphore value and wait if it is negative. If negative,}
{ the workstation will wait until it becomes non-negative or until a }
{ timeout occurs. }
Type Treq=Record
subf:byte;
_SemHandle:Longint;
_wait :word; { hi-lo }
end;
TPreq=^Treq;
begin
With TPreq(GlobalReqBuf)^
do begin
subf:=$02;
_semHandle:=Lswap(SemHandle);
_wait:=swap(wait_Time);
end;
F2SystemCall($20,SizeOf(treq),0,result);
WaitOnSemaphore:=(result=0);
end;
{F220/03 [3.x+]}
Function SignalSemaphore(SemHandle:LongInt) : Boolean;
{ Increment the semaphore value and release if waiting. If any stations}
{ are waiting, the station that has been waiting the longest will be }
{ signalled to proceed }
Type Treq=Record
subf:byte;
_semhandle:Longint;
end;
TPreq=^Treq;
begin
With TPreq(GlobalReqBuf)^
do begin
subf:=$03;
_semHandle:=Lswap(SemHandle);
end;
F2SystemCall($20,SizeOf(treq),0,result);
SignalSemaphore:=(result=0);
end;
{F220/04 [3.x+]}
Function CloseSemaphore(SemHandle:LongInt) : Boolean;
{ Decrement the open count of a semaphore. When the open count goes }
{ to zero, the semaphore is destroyed. }
Type Treq=Record
subf:byte;
_semhandle:Longint;
end;
TPreq=^Treq;
begin
With TPreq(GlobalReqBuf)^
do begin
subf:=$04;
_semHandle:=Lswap(SemHandle);
end;
F2SystemCall($20,SizeOf(treq),0,result);
CloseSemaphore:=(result=0);
end;
{F220/01 [2.x/3.x]}
FUNCTION ExamineSemaphore(SemHandle:LongInt;
VAR Value : Integer;
VAR OpenCount : Word ) : Boolean;
{ The semaphore value that comes back is the count from the open call }
{ - the open count is incremented }
{ anytime a station opens the semaphore this can be used for controlling }
{ the number of users using your software }
Type Treq=record
subf:byte;
_semHandle:Longint;
end;
Trep=record
_Value:Byte;
_OpenCount:Byte;
end;
TPreq=^Treq;
TPrep=^Trep;
BEGIN
With TPreq(GlobalReqBuf)^
DO begin
subf:=$01;
_semHandle:=Lswap(SemHandle);
end;
F2SystemCall($20,SizeOf(Treq),SizeOf(Trep),result);
With TPrep(GlobalReplyBuf)^
do begin
if (_Value and $80)>0
then Value:=254-_Value
else Value:=_Value;
OpenCount:=_OpenCount;
end;
ExamineSemaphore := (result = 0);
END;
{F217/F1 [2.15+? 3.x+]}
Function GetConnectionsSemaphores(ConnNbr:Word;
{i/o} Var seqNbr:Word;
{out} Var NbrOfSemaLeft:Byte;
{out} Var SemaInfo:TconnSema):Boolean;
{ To be called iteratively. Inital seqNbr=1. Iterate until seqNbr
becomes 0 (or until NbrOfSemaLeft becomes 0).
This function can return information about several semaphores at the
same time. However, the size of the reply buffer is limited, causing
several as of now unsolvable problems. For now this function will
return information on a per semaphore basis. }
Type Treq=Record
len:word;
subf:byte;
_ConnNbr:word; {lo-hi}
_SeqNbr:word; {lo-hi}
end;
Trep=record
_NextSeqNbr:word;
_nbrOfSema:byte; { word (lo-hi) ? }
_unknown:byte; { -^ }
_SemaInfoBuf:array[1..508] of byte;
end;
TPreq=^Treq;
TPrep=^Trep;
Var i,t:Byte;
begin
With TPreq(GlobalReqBuf)^
do begin
len:=SizeOf(Treq)-2;
subf:=$F1;
_ConnNbr:=ConnNbr;
_SeqNbr:=SeqNbr;
end;
F2SystemCall($17,SizeOf(treq),SizeOf(trep),result);
if result=0
then With TPrep(GlobalReplyBuf)^
do begin
NbrOfSemaLeft:=(_NbrOfSema-1);
if NbrOfSemaLeft=0
then seqNbr:=0
else seqNbr:=seqNbr+1; { unfortunately, _NextSeqNbr returns no valid info. }
Move(_SemaInfoBuf[1],SemaInfo,7+_SemaInfoBuf[7]);
With SemaInfo
do begin
Value:=swap(Value);
TaskNbr:=swap(TaskNbr);
end;
end;
GetConnectionsSemaphores:=(result=0);
{ 00 Successful C6 No console rights FD Bad connection number }
end;
{F217/F2 [2.15? 3.x+]}
Function GetSemaphoreInformation(SemaName:String;
{i/o} Var seqNbr:word;
{out} Var OpenCount:word;
Var SemValue:Integer;
Var NbrOfSemaLeft:byte;
Var info:TsemaInfoList):Boolean;
Type Treq=Record
len:word;
subf:byte;
_seqNbr: word;
_semaName:string[127];
end;
Trep=record
_NextSeqNbr:Word;
_OpenCount:word;
_SemValue:word;
_NbrOfRecords:word;
_SemaInfoBuf:array[1..514] of byte;
end;
TPreq=^Treq;
TPrep=^Trep;
begin
UpString(SemaName);
if SemaName[0]>#127
then SemaName[0]:=#127;
With TPreq(GlobalReqBuf)^
do begin
subf:=$F2;
_seqNbr:=seqNbr;
_SemaName:=SemaName;
len:=4+ord(_SemaName[0]);
end;
F2SystemCall($17,SizeOf(treq),SizeOf(trep),result);
With TPrep(GlobalReplyBuf)^
do begin
OpenCount:=_OpenCount;
SemValue:=Integer(_SemValue);
NbrOfSemaLeft:=_NbrOfRecords;
move(_SemaInfoBuf,Info,SizeOf(TsemaInfoList));
if NbrOfSemaLeft>100
then seqNbr:=seqNbr+100
else seqNbr:=0;
end;
GetSemaphoreInformation:=(result=0);
{ 00 Successful C6 No console rights }
end;
END.